﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using CCL.Utility;

namespace Server.Service
{
    /// <summary>
    /// 프로젝트 등록 요청에 대한 서비스를 제공합니다.
    /// </summary>
    public class RegistProject : IService
    {
        /// <summary>
        /// 요청받은 메시지의 본문
        /// </summary>
        CCL.SocketMessage.Request.RegistProject m_bodyMsg;

        /// <summary>
        /// 새로운 서비스를 생성합니다.
        /// </summary>
        /// <param name="bodyMsg">요청받은 메시지 본문</param>
        public RegistProject(CCL.SocketMessage.Request.RegistProject bodyMsg)
        {
            m_bodyMsg = bodyMsg;
        }

        /// <summary>
        /// 서비스를 시작합니다.
        /// </summary>
        /// <returns>전송할 byte배열</returns>
        public byte[] Execute()
        {
            byte[] returnBytes = null;
            using (SqlConnection conn = new SqlConnection(Properties.Resources.ConnectionString))
            {
                try
                {
                    conn.Open();

                    SqlCommand sqlCmd;

                    string projName = StringUtility.ConvertToStr(m_bodyMsg.ProjectName);

                    sqlCmd = new SqlCommand("INSERT INTO [Project](projectName, projectOwnerId) VALUES (@name, @id)", conn);
                    sqlCmd.Parameters.AddWithValue("@name", projName);
                    sqlCmd.Parameters.AddWithValue("@id", m_bodyMsg.ProjectOwnerID);

                    int execution = sqlCmd.ExecuteNonQuery();

                    if (execution <= 0)
                    {
                        throw new Exception("정상적으로 등록되지 않았습니다.");
                    }

                    sqlCmd = new SqlCommand(@"
                        SELECT 
                            [Project].projectId AS pid, 
                            [Project].headRevision AS head, 
                            [Project].projectOwnerId AS poid, 
                            [User].userId AS uid, 
                            [User].email AS email, 
                            [User].name AS name, 
                            [User].password AS password, 
                            [User].joinedDateTime AS joinedDate 
                        FROM [Project] 
                        INNER JOIN [User] 
                            ON [Project].projectOwnerId = [User].userId 
                        WHERE projectName = @name 
                            AND projectOwnerId = @id", conn);
                    sqlCmd.Parameters.AddWithValue("@name", projName);
                    sqlCmd.Parameters.AddWithValue("@id", m_bodyMsg.ProjectOwnerID);

                    int projId;
                    int head;
                    int owner;

                    int userId;
                    string email, name, password;
                    DateTime dateTime;

                    using (SqlDataReader reader = sqlCmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();

                            projId = (int)reader["pid"];
                            head = (int)reader["head"];
                            owner = (int)reader["poid"];

                            userId = (int)reader["uid"];
                            email = (string)reader["email"];
                            name = (string)reader["name"];
                            password = (string)reader["password"];
                            dateTime = (DateTime)reader["joinedDate"];
                        }
                        else
                        {
                            throw new Exception("정상적으로 등록되지 않았습니다.");
                        }
                    }

                    sqlCmd = new SqlCommand("INSERT INTO [ProjectMember](projectId, userId, permission) VALUES (@pid, @uid, @perm)", conn);
                    sqlCmd.Parameters.AddWithValue("@pid", projId);
                    sqlCmd.Parameters.AddWithValue("@uid", m_bodyMsg.ProjectOwnerID);
                    sqlCmd.Parameters.AddWithValue("@perm", CCL.SocketMessage.Constant.Permission.All);

                    if (sqlCmd.ExecuteNonQuery() <= 0)
                    {
                        throw new Exception("정상적으로 등록되지 않았습니다.");
                    }

                    CCL.TableStructure.User user = new CCL.TableStructure.User(userId, name, email, password, dateTime);
                    CCL.TableStructure.Project proj = new CCL.TableStructure.Project(projId, projName, head, user);
                    CCL.SocketMessage.Response.RegistProject resp = new CCL.SocketMessage.Response.RegistProject(proj);
                    CCL.SocketMessage.Message respMsg = CCL.SocketMessage.Message.MessageResponseBuilder(resp);

                    returnBytes = respMsg.GetByte();
                }
                catch (System.Exception ex)
                {
                    CCL.SocketMessage.Response.RegistProject resp = new CCL.SocketMessage.Response.RegistProject(ex.Message);
                    CCL.SocketMessage.Message respMsg = CCL.SocketMessage.Message.MessageResponseBuilder(resp);

                    returnBytes = respMsg.GetByte();
                }
            }

            return returnBytes;
        }
    }
}
